﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace QQTools.Data.Plus
{
    public static class QQDLL
    {
        // const  string dllPath = "D:\\CodeSpace\\C#\\QQTools\\QQTools-E\\QQTools.dll";
        const string dllPath = "QQTools.dll";
        /// <summary>
        /// 根据PID获取获取客户端key 长度64位 此Key权限最高  
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetClientKey(int pid);

        /// <summary>
        /// 根据QQ号和PID获取昵称
        /// </summary>
        /// <param name="Uin"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetClientName(string Uin, int pid);


        /// <summary>
        /// 获取指定QQ进程登陆的QQ号
        /// </summary>
        /// <param name="Uin"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetClientSelfUin(int pid);

        /// <summary>
        /// 用ClentKey获取Cookie
        /// </summary>
        /// <param name="Uin"></param>
        /// <param name="Clientkey"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetCookieByClentKey(string Uin, string Clientkey);


        /// <summary>
        /// 用HttpKey获取Cookie
        /// </summary>
        /// <param name="Uin"></param>
        /// <param name="HttpKey"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetCookieByHttpKey(string Uin, string HttpKey);

        /// <summary>
        /// 可用于 bkn，gtk，ldw计算
        /// </summary>
        /// <param name="Skey">Skey 或者P_Skey</param>
        /// <param name="Type">0-整数型，1-MD5型</param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetGtkBySkey(string Skey, int Type);


        /// <summary>
        /// 获取网页登陆的key 长度224位
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetHttpkey(int pid);


        /// <summary>
        /// 判断指定QQ是否在线
        /// </summary>
        /// <param name="Uin">QQ(Tim)登录的QQ （与Pid对应登录）</param>
        /// <param name="pid">QQ(Tim)的进程ID</param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr IsOnline(string Uin, int Pid);

        /// <summary>
        /// 根据PID获取群列表
        /// </summary>
        /// <param name="pid">QQ(Tim)的进程ID</param>
        /// <returns></returns>
        [DllImport(dllPath, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetGroupList(int Pid);

        //public string GetKey(Action action)
        //{
        //    IntPtr ptr = ()=> action;
        //    string key = Marshal.PtrToStringAnsi(ptr);
        //    FreeClientKey(ptr); // 显式释放内存
        //    return key;
        //}

        /// <summary>
        /// 获取QQ号(GetClientSelfUin获取到的QQ如果是负数可以调用这个)
        /// </summary>
        /// <param name="qq"></param>
        /// <returns></returns>

        public static void Test(object sender, EventArgs e)
        {
            try
            {
                Process[] processes = Process.GetProcessesByName("QQ");
                foreach (Process process in processes)
                {
                    // 1. 获取QQ
                    IntPtr resultPtr = GetClientSelfUin(process.Id);
                    // 在 C# 中通过 IntPtr 接收返回值，并使用 Marshal.PtrToStringAnsi 转换后立即释放内存（需与易语言约定释放方式）‌
                    string qq = Marshal.PtrToStringAnsi(resultPtr);
                    // 将qq转成long
                    Console.WriteLine($"qq:{qq}");

                    // 2. 根据httpkey获取cookie
                    resultPtr = GetClientName(qq, process.Id);
                    string nickname = Marshal.PtrToStringAnsi(resultPtr);
                    Console.WriteLine($"nickname:{nickname}");

                    // 3. 获取clientKey
                    resultPtr = GetClientKey(process.Id);
                    string clientKey = Marshal.PtrToStringAnsi(resultPtr);
                    Console.WriteLine($"clientKey:{clientKey}");

                    // 4. 根据ClentKey获取cookie
                    resultPtr = GetCookieByClentKey(qq, clientKey);
                    string cookieByClentKey = Marshal.PtrToStringAnsi(resultPtr);
                    Console.WriteLine($"cookieByClentKey:{cookieByClentKey}");

                    // 5. 获取httpkey
                    resultPtr = GetHttpkey(process.Id);
                    string httpkey = Marshal.PtrToStringAnsi(resultPtr);
                    Console.WriteLine($"httpkey:{httpkey}");

                    // 6. 根据httpkey获取cookie
                    resultPtr = GetCookieByClentKey(qq, clientKey);
                    string cookieByHttpkey = Marshal.PtrToStringAnsi(resultPtr);
                    Console.WriteLine($"cookieByHttpkey:{cookieByHttpkey}");


                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

    }
}
